package feishu

import (
	http "Hypnos-Soundcore/components/http"
	xlog "Hypnos-Soundcore/components/log"
	"Hypnos-Soundcore/constants"
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/pquerna/ffjson/ffjson"
	"log"
	nethttp "net/http"
	"time"
)

// FeiClient .
type FeiClient struct {
	globalConf Config
}

// SetConfig .
func (fc *FeiClient) SetConfig(conf Config) {
	fc.globalConf = conf
}

// GetWebhook .
func (fc *FeiClient) GetWebhook() string {
	return fc.globalConf.WebHook
}

// GetSecretKey .
func (fc *FeiClient) GetSecretKey() string {
	return fc.globalConf.SecretKey
}

// GenSign .
func (fc *FeiClient) GenSign() (string, string, error) {
	//timestamp + key 做sha256, 再进行base64 encode
	timestamp := fmt.Sprintf("%v", time.Now().Unix())
	stringToSign := fmt.Sprintf("%v", timestamp) + "\n" + fc.GetSecretKey()

	var data []byte
	h := hmac.New(sha256.New, []byte(stringToSign))
	_, err := h.Write(data)
	if err != nil {
		return "", "", err
	}

	signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
	return timestamp, signature, nil
}

// PostJson .
func (fc *FeiClient) PostJson(payload *PayLoad) (err error) {
	if len(fc.GetWebhook()) == 0 {
		err = errors.New("invalid webhook")
		return
	}
	var timestamp string
	var sign string
	if timestamp, sign, err = fc.GenSign(); err != nil {
		return
	}
	payload.Timestamp = timestamp
	payload.Sign = sign
	var resBody string
	if resBody, err = http.HttpPostJson(fc.GetWebhook(), payload); err != nil {
		//collector.MetricsTracingErrorTotal.With("callee", collector.CalleeFeiShuNotify).Inc()
		xlog.ErrorPrintf("FeishuNotify", "  prometheus gap error %s", err)
		return
	}
	if len(resBody) == 0 {
		err = errors.New("invalid response")
	}

	var response Response
	if err = ffjson.Unmarshal([]byte(resBody), &response); err != nil {
		return
	}
	if response.Code > 0 {
		err = errors.New(fmt.Sprintf("%s(%v)", response.Msg, response.Code))
	}
	return
}

// SendTextMessage .
func (fc *FeiClient) SendTextMessage(content string) error {
	payLoad := &PayLoad{MsgType: MsgTypeText, Content: &PayloadContent{Text: &content}}
	return fc.PostJson(payLoad)
}

// SendPostMessage .
func (fc *FeiClient) SendPostMessage(content PostContent) error {
	payLoad := &PayLoad{MsgType: MsgTypePost, Content: &PayloadContent{Post: &content}}
	return fc.PostJson(payLoad)
}

// SendPostMessageV2 .
func (fc *FeiClient) SendPostMessageV2(title, msg string) error {
	postItems := []PostItem{{Tag: TagText, Text: msg}}
	content := PostContent{LanguageZhCn: {Title: title, Content: [][]PostItem{postItems}}}
	payLoad := &PayLoad{MsgType: MsgTypePost, Content: &PayloadContent{Post: &content}}
	return fc.PostJson(payLoad)
}

// SendImageMessage .
func (fc *FeiClient) SendImageMessage(content string) error {
	payLoad := &PayLoad{MsgType: MsgTypeImage, Content: &PayloadContent{ImageKey: &content}}
	return fc.PostJson(payLoad)
}

// SendCardMessage .
func (fc *FeiClient) SendCardMessage(content CardContent) error {
	payLoad := &PayLoad{MsgType: MsgTypeInteractive, Card: &content}
	return fc.PostJson(payLoad)
}

// FeishuMessage 定义飞书消息的结构
type FeishuMessage struct {
	MsgType string `json:"msg_type"`
	Content struct {
		Text string `json:"text"`
	} `json:"content"`
}

// SendFeishuAlert 发送飞书告警消息
func SendFeishuAlert(webhookURL, message string) error {
	message = time.Now().Format(constants.CurrentTime) + "\n" + "飞书告警：" + message
	msg := FeishuMessage{
		MsgType: "text",
	}
	msg.Content.Text = "<at user_id = \"ou_14ecae362d39c3af6917cd48302e4e90\">ethan sun </at>" +
		"<at user_id = \"ou_e9fb29dc181957caffb9f3300adb7cc2\">zhiyong huang </at>" +
		"<at user_id = \"ou_b2b34571ecfb2359c17de17f11d6d491\">scofield yang </at>" + message

	jsonData, err := json.Marshal(msg)
	if err != nil {
		return fmt.Errorf("failed to marshal message: %v", err)
	}

	req, err := nethttp.NewRequest("POST", webhookURL, bytes.NewBuffer(jsonData))
	if err != nil {
		return fmt.Errorf("failed to create request: %v", err)
	}
	req.Header.Set("Content-Type", "application/json")

	client := &nethttp.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("failed to send request: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != nethttp.StatusOK {
		return fmt.Errorf("received non-200 response: %d", resp.StatusCode)
	}

	return nil
}

// SendFeishuInfo 发送飞书通知消息
func SendFeishuInfo(webhookURL, message string) error {
	message = time.Now().Format(constants.CurrentTime) + "\n" + "飞书通知：" + message
	msg := FeishuMessage{
		MsgType: "text",
	}
	msg.Content.Text = message

	jsonData, err := json.Marshal(msg)
	if err != nil {
		return fmt.Errorf("failed to marshal message: %v", err)
	}

	req, err := nethttp.NewRequest("POST", webhookURL, bytes.NewBuffer(jsonData))
	if err != nil {
		return fmt.Errorf("failed to create request: %v", err)
	}
	req.Header.Set("Content-Type", "application/json")

	client := &nethttp.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("failed to send request: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != nethttp.StatusOK {
		return fmt.Errorf("received non-200 response: %d", resp.StatusCode)
	}

	return nil
}

// 定义飞书消息告警函数
func SendFeishuAlertErr(webhookUrl string, err error) {
	if err == nil {
		return
	}

	// 构造消息内容
	msg := map[string]interface{}{
		"msg_type": "text",
		"content": map[string]string{
			"text": "<at user_id = \"ou_14ecae362d39c3af6917cd48302e4e90\">ethan sun </at>" +
				"<at user_id = \"ou_e9fb29dc181957caffb9f3300adb7cc2\">zhiyong huang </at>" +
				"<at user_id = \"ou_b2b34571ecfb2359c17de17f11d6d491\">scofield yang </at>" + "警告：发生错误 - " + time.Now().Format(constants.CurrentTime) + "\n" + err.Error(),
		},
	}

	// 序列化消息为JSON
	msgBytes, _ := json.Marshal(msg)
	body := bytes.NewBuffer(msgBytes)

	// 发送POST请求到飞书
	resp, err := nethttp.Post(webhookUrl, "application/json", body)
	if err != nil {
		log.Printf("发送飞书告警失败: %v", err)
		return
	}
	defer resp.Body.Close()

}
